package com.hqd.jjvm.rtda.heap;

import com.hqd.jjvm.classformat.constantpool.ConstantPool;
import com.hqd.jjvm.classformat.constantpool.ConstantStringInfo;
import com.hqd.jjvm.rtda.heap.ref.JSymRef;
import com.hqd.jjvm.rtda.memory.JMethodArea;
import com.hqd.jjvm.rtda.memory.JStringPool;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

/**
 * 运行时常量池
 */
@Getter
public class RuntimeConstantPool {
    private JClass jClass;
    private List<Object> constants;
    private JStringPool stringPool;

    public RuntimeConstantPool(JClass jClass, List<ConstantPool> constantPools) {
        this.jClass = jClass;
        this.constants = new ArrayList<>(constantPools.size());
        this.stringPool = JStringPool.getInstance();
        transformRuntimeConstantPool(constantPools);
    }

    private void transformRuntimeConstantPool(List<ConstantPool> constantPools) {
        for (ConstantPool constantPool : constantPools) {
            Object val = constantPool.getVal();
            if (val instanceof JSymRef) {
                ((JSymRef) val).setJClass(jClass);
            } else if (constantPool instanceof ConstantStringInfo) {
                if (JMethodArea.getJClass(Object.class.getName()) != null && JMethodArea.getJClass(Object.class.getName()).getState().isEndLinked()) {
                    if (JMethodArea.getJClass(String.class.getName()) != null && JMethodArea.getJClass(String.class.getName()).getState().isEndLinked())
                        stringPool.addString(jClass.getLoader(), constantPool.getVal().toString());
                }
            }
            this.constants.add(val);
        }
    }

    public Object getConstantVal(int index) {
        return this.constants.get(index);
    }

}
